import React, { useEffect, useRef, useState } from 'react'
import { BackTop, Button } from '@arco-design/web-react';
import { connect } from 'react-redux'
import $ from 'jquery'
import './index.css'
import jquery from 'jquery';

function Main(props) {
    $('#custom_backtop').mouseup(function () {
        TextHighlight();
    });

    var anchorNode,
        focusNode;

    function TextHighlight() {
        var sel = window.getSelection(),
            anchorNode = sel.anchorNode,
            focusNode = sel.focusNode,
            anchorOffset = sel.anchorOffset,
            focusOffset = sel.focusOffset;

        // anchorNode 和 focusNode 属于同一个文本节点
        if (anchorNode === focusNode) {
            var tc = anchorNode.textContent,
                cs = tc.substring(0, anchorOffset),
                cm = tc.substring(anchorOffset, focusOffset),
                ce = tc.substring(focusOffset),
                newTc = cs + '<span style="background:yellow">' + cm + '</span>' + ce;
            $(anchorNode).replaceWith(newTc);	//////////////////	      
        }
        // 跨标签高亮
        else {

            // 分别获取 anchorNode 和 focusNode 祖先节点
            var anchorAncestors = findAncestorNodes(anchorNode),
                focusAncestors = findAncestorNodes(focusNode),

                // 找到 anchorNode 和 focusNode 的第一个公共祖先节点
                indexA,
                indexF,
                isFind = false;

            for (var i = 0; i < anchorAncestors.length; i++) {
                if (isFind) break;
                for (var j = 0; j < focusAncestors.length; j++) {
                    if (anchorAncestors[i] == focusAncestors[j]) {
                        indexA = i;
                        indexF = j;
                        isFind = true;
                        break;
                    }
                }
            }

            // 对 anchorNode 所属子树以其祖先节点为分界对右侧节点进行高亮
            for (var i = 0; i < indexA - 1; i++) {
                highlightRightSiblings(anchorAncestors[i])
            }

            // 对 focusNode 所属子树以其祖先节点为分界对左侧节点进行高亮
            for (var j = 0; j < indexF - 1; j++) {
                highlightLeftSiblings(focusAncestors[j])
            }

            // 对以公共祖先节点为根节点的中间子树进行高亮
            var midRoot = anchorAncestors[indexA - 1].nextSibling;
            while (midRoot != null && midRoot != focusAncestors[indexF - 1]) {
                //对midRoot进行高亮时会改变其DOM结构，所以需在高亮前对其nextSibling节点进行缓存
                var tmp = midRoot.nextSibling;
                highLightNode(midRoot);
                midRoot = tmp;
            }

            // 对 anchorNode 进行高亮
            var tcA = anchorNode.textContent,
                csA = tcA.substring(0, anchorOffset),
                ceA = tcA.substring(anchorOffset),
                newTcA = csA + '<span style="background:yellow">' + ceA + '</span>';
            $(anchorNode).replaceWith(newTcA);

            // 对 focusNode 进行高亮
            var tcF = focusNode.textContent,
                csF = tcF.substring(0, focusOffset),
                ceF = tcF.substring(focusOffset),
                newTcF = '<span style="background:yellow">' + csF + '</span>' + ceF;
            $(focusNode).replaceWith(newTcF);

            // 跨标签高亮时需要手动取消焦点。。。为什么啊啊啊啊 
            // bug： 选行数很多时 mouseup 之后不执行 textHight() - -||||
            $('#key').focus();
        }

    }


    // 获取一个节点的所有祖先节点
    function findAncestorNodes(node) {
        var ancestors = [];
        var cursor = node;
        ancestors.push(cursor);

        while (cursor != document.body) {
            cursor = cursor.parentNode;
            ancestors.push(cursor);
        }
        return ancestors;
    }

    // 将一个节点及其所有右侧兄弟节点进行高亮
    function highlightRightSiblings(node) {
        highLightNode(node);
        if (!node.nextSibling) {
            return;
        } else {
            highlightRightSiblings(node.nextSibling);
        }
    }

    // 将一个节点及其所有左侧兄弟节点进行高亮
    function highlightLeftSiblings(node) {
        highLightNode(node);
        if (!node.previousSibling) {
            return;
        } else {
            highlightLeftSiblings(node.previousSibling);
        }
    }

    // 高亮节点的递归实现，如果是文本节点则直接高亮，如果是元素节点则将其所有文本子节点进行高亮
    function highLightNode(node) {
        if (node.nodeType == 3 &&
            /[^\n\r\s]/.test(node.nodeValue) &&	// 排除所有只包含回车、换行或空格的文本呢节点
            node != anchorNode &&
            node != focusNode) {
            var span = document.createElement('span');
            span.style.background = 'yellow';
            $(node).wrap($(span));
        }
        if (node.nodeType == 1) {
            var childNodes = node.childNodes;
            if (childNodes.length > 0) {
                for (var i = 0; i < childNodes.length; i++) {
                    highLightNode(childNodes[i])
                }
            }
        }
    }

    window.TextHighlight = TextHighlight;







    const [mytext, setmytext] = useState("没有正文")
    let timer = null;
    const handleReadPro = () => {
        clearTimeout(timer);
        timer = setTimeout(() => {
            let scrollTop = document.getElementById('custom_backtop').scrollTop
            let scrollHeight = document.getElementById('custom_backtop').scrollHeight;
            let clientHeight = document.getElementById('custom_backtop').clientHeight;
            let readProcess = +(scrollTop / (scrollHeight - clientHeight)).toFixed(2) * 100;
            props.Change_ReadPro(readProcess)
        }, 1500);
    }

    useEffect(() => {
        document.getElementById('custom_backtop').addEventListener('scroll', handleReadPro)
    })
    useEffect(() => {
        getData();
    }, [props.BG_Color, props.fontColor, props.fontsize, props.keyword, props.wordcolor])



    function debounce(fn, delay = 500) {
        let timer = null;
        return function () {
            if (timer) {
                clearTimeout(timer);
            }
            timer = setTimeout(() => {
                fn.apply(this, arguments);
                timer = null;
            }, delay)
        }
    }


    const getData = () => {
        fetch(`http://localhost:3000/htmlans`, {
            mode: "no-cors"
        }).then(res => res.text()).then(
            data => {

                var f = document.getElementById("custom_backtop");
                var fcolor, bgcolor;
                switch (props.fontColor) {
                    case "red": fcolor = "rgb(238, 72, 50)"; break;
                    case "blue": fcolor = "rgb(83, 124, 177)"; break;
                    case "white": fcolor = "white"; break;
                    case "black": fcolor = "black"; break;
                    default: ;
                }
                switch (props.BG_Color) {
                    case "green": bgcolor = "rgb(129, 188, 121, 0.781)"; break;
                    case "blue": bgcolor = "rgba(124, 179, 211, 0.781)"; break;
                    case "white": bgcolor = "white"; break;
                    case "black": bgcolor = "black"; break;
                    default: ;
                }
                f.style.color = fcolor;
                f.style.backgroundColor = bgcolor;

                f.style.fontSize = props.fontsize;
                let color = props.wordcolor;
                let hightlightText = data;
                if (props.keyword !== "") {
                    hightlightText = data.replace(new RegExp(`(${props.keyword})`, 'g'), `<span><font color=${color}>${props.keyword}</font></span>`);
                }
                f.innerHTML = hightlightText;
            }
        )
    }
    return (
        <div style={{ position: 'relative', padding: '8px 12px' }} className='main-box'>
            <BackTop
                style={{ position: 'absolute' }}
                visibleHeight={30}
                target={() => document.getElementById('custom_backtop')}
            >
                <Button type='primary' iconOnly style={{ width: 40, height: 40 }}>UP</Button>
            </BackTop>
            <div id='custom_backtop' style={{ overflow: 'auto' }}  >
            </div>
        </div>
    )
}



const mapStateToProps = ({ FontColorReducer, BG_ColorReducer, FontSizeReducer, KeyWordReducer, Word_ColorReducer }) => ({
    fontColor: FontColorReducer,
    BG_Color: BG_ColorReducer,
    fontsize: FontSizeReducer,
    keyword: KeyWordReducer,
    wordcolor: Word_ColorReducer

})
const mapDispatchToProps = {
    Change_ReadPro(process) {
        return {
            type: 'change_readpro',
            payload: process
        }
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(Main)